package com.yang.library.client;


import com.fasterxml.jackson.databind.ObjectMapper;
import com.yang.library.bookenum.State;
import com.yang.library.bookenum.Role;
import com.yang.library.bookenum.TCPEnum;
import com.yang.library.client.menu.AdminBookMenu;
import com.yang.library.client.menu.UserBookMenu;
import com.yang.library.entry.User;
import com.yang.library.util.AppContext;
import com.yang.library.util.Constant;
import com.yang.library.util.PrintUtils;

import java.io.*;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

public class AppClient {
    private final ObjectMapper mapper = AppContext.getInstance().getMapper();

    public static void main(String[] args) {
        new AppClient().start();
    }

    public void start() {
        try {
            Socket socket = new Socket(Constant.SERVER_IP, Constant.SERVER_PORT);
            BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.UTF_8));
            AppContext.getInstance().setSocket(socket);
            System.out.println("欢迎来到图书管理系统");
            while (true) {
                System.out.println("==========图书管理系统==============");
                System.out.println("1. 注册");
                System.out.println("2. 登录");
                System.out.println("3. 退出系统");

                int type = PrintUtils.getIntInput(AppContext.getInstance().getScanner(), "请输入您的选择:");
                switch (type) {
                    case 1:
                        register(reader, writer);
                        break;
                    case 2:
                        login(reader, writer);
                        break;
                    case 3:
                        System.out.println("谢谢使用!");
                        socket.close();
                        return;
                    default:
                        System.out.println("输入有误，请重新输入！");
                        break;
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private void login(BufferedReader reader, BufferedWriter writer) throws Exception {
        String username = PrintUtils.getInput("请输入用户名:");
        String password = PrintUtils.getInput("请输入密码:");
        writer.write(mapper.writeValueAsString(TCPEnum.USER_LOGIN) + Constant.NEW_LINE);
        writer.write(mapper.writeValueAsString(username) + Constant.NEW_LINE);
        writer.write(mapper.writeValueAsString(password) + Constant.NEW_LINE);
        writer.flush();

        // 获取服务端的响应
        String responseMsg = reader.readLine();
        if (responseMsg == null) {
            System.out.println("登录失败!");
            return;
        }
        State response = mapper.readValue(responseMsg, State.class);
        String role = mapper.readValue(reader.readLine(), String.class);
        switch (response) {
            case SUCCESS:
                System.out.println("登录成功!");
                AppContext.getInstance().setUserName(username);
                AppContext.getInstance().setPassword(password);
                menuController(role);
                return;
            case FAILURE:
                System.out.println("登录失败!");
                break;
        }
    }

    private void menuController(String role) {
        switch (Role.fromString(role)) {
            case Role.ADMIN:
                new AdminBookMenu(AppContext.getInstance().getSocket()).start();
                break;
            case Role.USER:
                new UserBookMenu(AppContext.getInstance().getSocket()).start();
                break;
        }
    }

    private void register(BufferedReader reader, BufferedWriter writer) throws Exception {
        String username = PrintUtils.getInput("请输入用户名:");
        String password = PrintUtils.getInput("请输入密码:");
        String role = PrintUtils.getInput("请输入用户角色:");
        User user = new User(username, password, role);
        writer.write(mapper.writeValueAsString(TCPEnum.USER_REGISTER) + Constant.NEW_LINE);
        writer.write(mapper.writeValueAsString(user) + Constant.NEW_LINE);
        writer.flush();

        // 获取服务端的响应
        String responseMsg = reader.readLine();
        if (responseMsg == null) {
            System.out.println("注册失败!");
            return;
        }
        State response = mapper.readValue(responseMsg, State.class);
        switch (response) {
            case SUCCESS:
                System.out.println("注册成功!");
                return;
            case FAILURE:
                System.out.println("注册失败!");
                break;
        }
    }
}
